package com.x.scratch.controller;

import com.alibaba.fastjson.JSON;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.x.framework.Base;
import com.x.framework.exception.BusinessException;
import com.x.framework.redis.XRedisTemplate;
import com.x.scratch.model.User;
import com.x.scratch.service.UserService;
import com.x.scratch.util.Constant;
import com.x.scratch.util.HttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.MessageFormat;
import java.util.*;

@Controller
@RestController
public class WxController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    private static ModelAndView loginView = new ModelAndView("login.jsp");

    @Autowired
    private UserService userService;

    @Autowired
    private WXPay wxPay;

    @Autowired
    private XRedisTemplate xRedisTemplate;

    public WxController() {

    }

    @RequestMapping(
            value = {"/wx/authorize"},
            method = {RequestMethod.POST, RequestMethod.GET}
    )
    public void authorize(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("******************WX_AUTHORIZE_URL=" + Constant.WX_AUTHORIZE_URL);
        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        request.setCharacterEncoding("UTF-8");
//        String redirectUri = URLEncoder.encode(Constant.WX_REDIRECT_URL, "UTF-8");
        response.sendRedirect(Constant.WX_AUTHORIZE_URL);
    }


    @RequestMapping(
            value = {"/wx/token"},
            method = {RequestMethod.POST, RequestMethod.GET}
    )
    public void token(HttpServletRequest request, HttpServletResponse response) {
        try {
            Map<String, Object> tokenMap = this.getTokenByCode(request);
            String openid = tokenMap.get(Constant.OPENID).toString();
            String accessToken = tokenMap.get(Constant.ACCESS_TOKEN).toString();
            xRedisTemplate.set(Constant.WX_OPENID_ + openid, accessToken, 7200);

            Map<String, Object> userInfoMap = this.getUserInfoByTokenOpenId(accessToken, openid);

            User user = new User();
            user.setUserOpenId(openid);
            List<User> userList = userService.selectUserList(user);
            if (userList.size() > 0) {
                user = userList.get(0);
                user.setUserNickName((String) userInfoMap.get("nickname"));
                user.setUserSex((Integer) userInfoMap.get("sex"));
                user.setUserHeadImgUrl((String) userInfoMap.get("headimgurl"));
                user.setUserCountry((String) userInfoMap.get("country"));
                user.setUserProvince((String) userInfoMap.get("province"));
                user.setUserCity((String) userInfoMap.get("city"));
                user.setUserToken(accessToken);
                user.setUserUpdateTime(Base.getDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
                userService.updateUser(user);
            } else {
                user.setUserNickName((String) userInfoMap.get("nickname"));
                user.setUserSex((Integer) userInfoMap.get("sex"));
                user.setUserHeadImgUrl((String) userInfoMap.get("headimgurl"));
                user.setUserCountry((String) userInfoMap.get("country"));
                user.setUserProvince((String) userInfoMap.get("province"));
                user.setUserCity((String) userInfoMap.get("city"));
                user.setUserToken(accessToken);
                user.setUserCreateTime(Base.getDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
                user.setUserUpdateTime(user.getUserCreateTime());
                user = userService.insertUser(user);
            }

            request.setAttribute("openid", openid);
            request.setAttribute("accessToken", accessToken);
            request.setAttribute("url", "/wx/pay.jsp");

            request.getRequestDispatcher("/login.jsp").forward(request, response);
//            return loginView;
        } catch (Exception e) {
            throw new BusinessException("wx get token is wrong", e);
        }
    }


    @RequestMapping(
            value = {"/wx/pay/notify"},
            method = {RequestMethod.POST, RequestMethod.GET}
    )
    public ModelAndView payNotify(HttpServletRequest request, HttpServletResponse response) {
        try {
            Map map = request.getParameterMap();
            System.out.println("==========================================--------------------============");
            return loginView;
        } catch (Exception e) {
            throw new BusinessException("wx get token is wrong", e);
        }
    }

    private Map<String, Object> getTokenByCode(HttpServletRequest request) throws Exception {
        String echostr = request.getParameter("echostr");
        logger.info("******************echostr=" + echostr);
        if (echostr == null) {
            String code = request.getParameter("code");
            logger.info("******************code=" + code);
            if (code != null) {
                String wxTokenUrl = MessageFormat.format(Constant.WX_TOKEN_URL, code);
                logger.info("******************wxTokenUrl=" + wxTokenUrl);
                Map<String, Object> tokenMap = HttpClient.httpRequestJson(wxTokenUrl, Constant.GET, null);
                return tokenMap;
            }
        } else {
            logger.error("echostr is null");
        }
        return null;
    }

    private Map<String, Object> getUserInfoByTokenOpenId(String accessToken, String openid) {
        String wxUserInfoUrl = MessageFormat.format(Constant.WX_USERINFO_URL, accessToken, openid);
        logger.info("******************wxUserInfoUrl=" + wxUserInfoUrl);
        Map<String, Object> userInfoMap = HttpClient.httpRequestJson(wxUserInfoUrl, Constant.GET, null);
        return userInfoMap;
    }

//    public String getPrepayId(HttpServletRequest request, String name, String orderno, String total_fee, String openid) {
//        SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
//        parameters.put("appid", Constant.WX_APP_ID);
//        parameters.put("mch_id", Constant.WX_PAY_MCHID);
//        parameters.put("nonce_str", CreateNoncestr());
//        parameters.put("body", name);
//        parameters.put("out_trade_no", orderno);// 订单号
//        parameters.put("total_fee", total_fee);// 支付金额单位：分
//        parameters.put("spbill_create_ip", getIp2(request));
//        parameters.put("notify_url", "支付成功回调地址");
//        parameters.put("trade_type", "JSAPI");
//        parameters.put("openid", openid);//openid :需填写
//        parameters.put("time_expire", "20201230240000");// 交易结束时间,需要动态传入,格式为yyyyMMddHHmmss
//        String sign = createSign("UTF-8", parameters);
//        parameters.put("sign", sign);
//        String requestXML = getRequestXml(parameters);
//        //调用统一下单接口
//        Map<String, Object> map = HttpClient.httpRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", requestXML);
//        return map.get("prepay_id").toString();
//    }
//
//    @SuppressWarnings("rawtypes")
//    public static String createSign(String characterEncoding, SortedMap<Object, Object> parameters) {
//        StringBuffer sb = new StringBuffer();
//        Set es = parameters.entrySet();
//        Iterator it = es.iterator();
//        while (it.hasNext()) {
//            Map.Entry entry = (Map.Entry) it.next();
//            String k = (String) entry.getKey();
//            Object v = entry.getValue();
//            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
//                sb.append(k + "=" + v + "&");
//            }
//        }
//        sb.append("key=" + Constant.WX_PAY_KEY);
//        String sign = MD5Encode(sb.toString(), characterEncoding).toUpperCase();
//        return sign;
//    }
//
//    public static String MD5Encode(String origin, String charsetname) {
//        String resultString = null;
//        try {
//            resultString = new String(origin);
//            MessageDigest md = MessageDigest.getInstance("MD5");
//            if (charsetname == null || "".equals(charsetname))
//                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
//            else
//                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
//        } catch (Exception exception) {
//        }
//        return resultString;
//    }
//
//    private static String byteArrayToHexString(byte b[]) {
//        StringBuffer resultSb = new StringBuffer();
//        for (int i = 0; i < b.length; i++)
//            resultSb.append(byteToHexString(b[i]));
//        return resultSb.toString();
//    }
//
//    private static String byteToHexString(byte b) {
//        int n = b;
//        if (n < 0)
//            n += 256;
//        int d1 = n / 16;
//        int d2 = n % 16;
//        return hexDigits[d1] + hexDigits[d2];
//    }
//
//    public static String create_nonce_str() {
//        return UUID.randomUUID().toString();
//    }
//
//    public static String create_timestamp() {
//        return Long.toString(System.currentTimeMillis() / 1000);
//    }

}
